home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / RCS / ttyPdev.c,v < prev    next >
Text File  |  1990-02-28  |  21KB  |  788 lines

  1. head     1.8;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.8
  10. date     90.02.28.11.10.55;  author brent;  state Exp;
  11. branches ;
  12. next     1.7;
  13.  
  14. 1.7
  15. date     89.06.29.16.24.23;  author ouster;  state Exp;
  16. branches ;
  17. next     1.6;
  18.  
  19. 1.6
  20. date     89.06.15.15.09.37;  author ouster;  state Exp;
  21. branches ;
  22. next     1.5;
  23.  
  24. 1.5
  25. date     89.06.03.16.47.26;  author ouster;  state Exp;
  26. branches ;
  27. next     1.4;
  28.  
  29. 1.4
  30. date     89.06.02.13.38.39;  author brent;  state Exp;
  31. branches ;
  32. next     1.3;
  33.  
  34. 1.3
  35. date     89.04.20.10.24.21;  author ouster;  state Exp;
  36. branches ;
  37. next     1.2;
  38.  
  39. 1.2
  40. date     89.04.20.10.23.14;  author ouster;  state Exp;
  41. branches ;
  42. next     1.1;
  43.  
  44. 1.1
  45. date     89.04.20.10.04.16;  author ouster;  state Exp;
  46. branches ;
  47. next     ;
  48.  
  49.  
  50. desc
  51. @@
  52.  
  53.  
  54. 1.8
  55. log
  56. @Updated to new Td_ControlCooked interface
  57. @
  58. text
  59. @/* 
  60.  * ttyPdev.c --
  61.  *
  62.  *    This file provides a bridge between the pdev and td modules to
  63.  *    produce a pseudo-device that behaves like a terminal.
  64.  *
  65.  * Copyright 1989 Regents of the University of California
  66.  * Permission to use, copy, modify, and distribute this
  67.  * software and its documentation for any purpose and without
  68.  * fee is hereby granted, provided that the above copyright
  69.  * notice appear in all copies.  The University of California
  70.  * makes no representations about the suitability of this
  71.  * software for any purpose.  It is provided "as is" without
  72.  * express or implied warranty.
  73.  */
  74.  
  75. #ifndef lint
  76. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyPdev.c,v 1.7 89/06/29 16:24:23 ouster Exp Locker: brent $ SPRITE (Berkeley)";
  77. #endif /* not lint */
  78.  
  79. #include <pdev.h>
  80. #include <status.h>
  81. #include <stdlib.h>
  82. #include <string.h>
  83. #include <td.h>
  84.  
  85. /*
  86.  * Library imports:
  87.  */
  88.  
  89. extern void panic();
  90.  
  91. /*
  92.  * One of the following structures is created for each call to
  93.  * Td_CreatePdev:
  94.  */
  95.  
  96. typedef struct {
  97.     Pdev_Token pdev;            /* Token returned by Pdev_Open. */
  98.     char *pdevName;            /* Name of pseudo-device file
  99.                      * (malloc'ed). */
  100.     Td_Terminal term;            /* Token returned by Td_Create. */
  101.     int selectState;            /* Current select state of terminal;
  102.                      * a combination of FS_READABLE,
  103.                      * FS_WRITABLE, and FS_EXCEPTION. */
  104. } PdevTerm;
  105.  
  106. /*
  107.  * Forward declarations to procedures defined later in this file:
  108.  */
  109.  
  110. static int    ChangeReady();
  111. static int    CookedProc();
  112. static int    PdevClose();
  113. static int    PdevIoctl();
  114. static int    PdevOpen();
  115. static int    PdevRead();
  116. static int    PdevWrite();
  117. static int    SendSignal();
  118.  
  119. /*
  120.  *----------------------------------------------------------------------
  121.  *
  122.  * Td_CreatePdev --
  123.  *
  124.  *    Create a terminal with a pseudo-device attached to it.
  125.  *
  126.  * Results:
  127.  *    The return value is a handle that may be passed to
  128.  *    Td_DeletePdev to close the pseudo-terminal.  The Td_Terminal
  129.  *    token for the terminal gets stored at *termPtr, for the
  130.  *    caller's use in communicating with the terminal driver.
  131.  *    If a pseudo-device couldn't be opened, then the return value
  132.  *    is NULL and an error message is stored in pdev_ErrorMsg.
  133.  *
  134.  * Side effects:
  135.  *    A Td_Terminal is created with its "cooked" side attached
  136.  *    to a pseudo-device managed by this module.  The caller
  137.  *    must use the Fs_Select facilities so that this module
  138.  *    gets callbacks from the Pdev library.
  139.  *
  140.  *----------------------------------------------------------------------
  141.  */
  142.  
  143. Td_Pdev
  144. Td_CreatePdev(name, realNamePtr, termPtr, rawProc, clientData)
  145.     char *name;            /* Name of file to use for pseudo-device. */
  146.     char **realNamePtr;        /* Where to store pointer to actual name
  147.                  * used. */
  148.     Td_Terminal *termPtr;    /* Token for the Td_Terminal gets written
  149.                  * here, if this is non-NULL. */
  150.     int (*rawProc)();        /* Procedure for Td module to call to
  151.                  * handle control requests on raw side
  152.                  * of terminal. */
  153.     ClientData clientData;    /* Arbitrary data value to pass to rawProc. */
  154. {
  155.     Pdev_CallBacks callbacks;
  156.     register PdevTerm *ptPtr;
  157.  
  158.     ptPtr = (PdevTerm *) malloc(sizeof(PdevTerm));
  159.     callbacks.open = PdevOpen;
  160.     callbacks.read = PdevRead;
  161.     callbacks.write = PdevWrite;
  162.     callbacks.ioctl = PdevIoctl;
  163.     callbacks.close = PdevClose;
  164.     ptPtr->pdev = Pdev_Open(name, realNamePtr, 1000, 0,
  165.         &callbacks, (ClientData) ptPtr);
  166.     if (ptPtr->pdev == NULL) {
  167.     free((char *) ptPtr);
  168.     return (Td_Pdev) NULL;
  169.     }
  170.     if (realNamePtr != NULL) {
  171.     name = *realNamePtr;
  172.     }
  173.     ptPtr->pdevName = malloc((unsigned) (strlen(name) + 1));
  174.     strcpy(ptPtr->pdevName, name);
  175.     ptPtr->term = Td_Create(1000, CookedProc, (ClientData) ptPtr,
  176.         rawProc, clientData);
  177.     ptPtr->selectState = FS_WRITABLE;
  178.  
  179.     if (termPtr != NULL) {
  180.     *termPtr = ptPtr->term;
  181.     }
  182.     return (Td_Pdev) ptPtr;
  183. }
  184.  
  185. /*
  186.  *----------------------------------------------------------------------
  187.  *
  188.  * Td_DeletePdev --
  189.  *
  190.  *    Delete a pseudo-device and the Td_Terminal associated with it.
  191.  *
  192.  * Results:
  193.  *    None.
  194.  *
  195.  * Side effects:
  196.  *    The memory and state associated with the pseudo device and
  197.  *    terminal are recycled.  The pseudo-device file is destroyed,
  198.  *    if that is possible.
  199.  *
  200.  *----------------------------------------------------------------------
  201.  */
  202.  
  203. void
  204. Td_DeletePdev(ttyPdev)
  205.     Td_Pdev ttyPdev;        /* Pseudo-terminal to destroy. */
  206. {
  207.     register PdevTerm *ptPtr = (PdevTerm *) ttyPdev;
  208.  
  209.     /*
  210.      * Close the terminal first, so that hangups can be sent to
  211.      * processes.
  212.      */
  213.  
  214.     Td_Delete(ptPtr->term);
  215.     Pdev_Close(ptPtr->pdev);
  216.     unlink(ptPtr->pdevName);
  217.     free(ptPtr->pdevName);
  218.     free((char *) ptPtr);
  219. }
  220.  
  221. /*
  222.  *----------------------------------------------------------------------
  223.  *
  224.  * PdevOpen --
  225.  *
  226.  *    This procedure is called back by the Pdev module whenever
  227.  *    a pseudo-terminal is being opened.
  228.  *
  229.  * Results:
  230.  *    None.
  231.  *
  232.  * Side effects:
  233.  *    None.
  234.  *
  235.  *----------------------------------------------------------------------
  236.  */
  237.  
  238.     /* ARGSUSED */
  239. static int
  240. PdevOpen(ptPtr, newStream, readBuffer, flags, procID, hostID,
  241.     uid, selectBitsPtr)
  242.     register PdevTerm *ptPtr;    /* Our information about the pdev. */
  243.     Pdev_Stream *newStream;    /* Service stream associated with the
  244.                  * new open. */
  245.     char *readBuffer;        /* Read buffer:  not used here. */
  246.     int flags;            /* Flags from open kernel call (not used). */
  247.     int procID;            /* Process doing open (not used). */
  248.     int hostID;            /* Host where process is running (not used). */
  249.     int uid;            /* Effective user id of pid (not used). */
  250.     int *selectBitsPtr;        /* Store select state of new stream here. */
  251. {
  252.     int result;
  253.     Boolean true = TRUE;
  254.     ReturnStatus status;
  255.  
  256.     newStream->clientData = (ClientData) ptPtr;
  257.     result = Td_Open(ptPtr->term, &ptPtr->selectState);
  258.     *selectBitsPtr = ptPtr->selectState;
  259.     status = Fs_IOControl(newStream->streamID, IOC_PDEV_WRITE_BEHIND,
  260.         sizeof(int), (Address) &true, 0, (Address) NULL);
  261.     if (status != SUCCESS) {
  262.     panic("PdevOpen couldn't enable write-behind:  %s",
  263.         Stat_GetMsg(status));
  264.     }
  265.     return result;
  266. }
  267.  
  268. /*
  269.  *----------------------------------------------------------------------
  270.  *
  271.  * PdevClose --
  272.  *
  273.  *    This procedure is called back by the Pdev module when all of
  274.  *    the streams corresponding to one "open" on a pseudo-terminal
  275.  *    have now been closed.
  276.  *
  277.  * Results:
  278.  *    Always returns zero.
  279.  *
  280.  * Side effects:
  281.  *    State in the terminal is updated.
  282.  *
  283.  *----------------------------------------------------------------------
  284.  */
  285.  
  286. static int
  287. PdevClose(streamPtr)
  288.     Pdev_Stream *streamPtr;    /* Service stream that is about to go away. */
  289. {
  290.     Td_Close(((PdevTerm *) streamPtr->clientData)->term);
  291.     return 0;
  292. }
  293.  
  294. /*
  295.  *----------------------------------------------------------------------
  296.  *
  297.  * PdevRead --
  298.  *
  299.  *    This procedure is called back by the Pdev module whenever
  300.  *    a client tries to read the pseudo-device associated with
  301.  *    a terminal.
  302.  *
  303.  * Results:
  304.  *    None.
  305.  *
  306.  * Side effects:
  307.  *    None.
  308.  *
  309.  *----------------------------------------------------------------------
  310.  */
  311.  
  312.     /* ARGSUSED */
  313. static int
  314. PdevRead(streamPtr, readPtr, freeItPtr, selectBitsPtr, sigPtr)
  315.     Pdev_Stream *streamPtr;    /* Service stream the client specified in its
  316.                  * kernel call. */
  317.     Pdev_RWParam *readPtr;    /* Read parameter block.  Indicates size,
  318.                  * buffer, plus various IDs */
  319.     Boolean *freeItPtr;        /* Not used here. */
  320.     int *selectBitsPtr;        /* Store new select state of terminal here. */
  321.     Pdev_Signal *sigPtr;
  322. {
  323.     int result;
  324.     register PdevTerm *ptPtr = (PdevTerm *) streamPtr->clientData;
  325.  
  326.     result = Td_GetCooked(ptPtr->term, readPtr->procID, readPtr->familyID,
  327.         &readPtr->length, readPtr->buffer, &sigPtr->signal,
  328.         &ptPtr->selectState);
  329.     *selectBitsPtr = ptPtr->selectState;
  330.     return result;
  331. }
  332.  
  333. /*
  334.  *----------------------------------------------------------------------
  335.  *
  336.  * PdevWrite --
  337.  *
  338.  *    This procedure is called back by the Pdev module whenever
  339.  *    a client tries to write the pseudo-device associated with
  340.  *    a terminal.  Note:  these writes are always asynchronous.
  341.  *
  342.  * Results:
  343.  *    None.
  344.  *
  345.  * Side effects:
  346.  *    None.
  347.  *
  348.  *----------------------------------------------------------------------
  349.  */
  350.  
  351.     /* ARGSUSED */
  352. static int
  353. PdevWrite(streamPtr, async, writePtr, selectBitsPtr, sigPtr)
  354.     Pdev_Stream *streamPtr;    /* Service stream the client specified in its
  355.                  * kernel call. */
  356.     int async;            /* Non-zero means this is an asynchronous
  357.                  * write request (should always be TRUE). */
  358.     Pdev_RWParam *writePtr;    /* Write parameter block.  Indicates size,
  359.                  * offset, and buffer, among other things */
  360.     int *selectBitsPtr;        /* Store new select state of terminal here. */
  361.     Pdev_Signal *sigPtr;    /* Signal to return, if any */
  362. {
  363.     register PdevTerm *ptPtr = (PdevTerm *) streamPtr->clientData;
  364.     int oldBits, result;
  365.  
  366.     oldBits = ptPtr->selectState;
  367.     result = Td_PutCooked(ptPtr->term, &writePtr->length, writePtr->buffer,
  368.         &sigPtr->signal, &ptPtr->selectState);
  369.     if (ptPtr->selectState != oldBits) {
  370.     Pdev_EnumStreams(ptPtr->pdev, ChangeReady,
  371.         (ClientData) ptPtr->selectState);
  372.     }
  373.     *selectBitsPtr = ptPtr->selectState;
  374.     return result;
  375. }
  376.  
  377. /*
  378.  *----------------------------------------------------------------------
  379.  *
  380.  * PdevIoctl --
  381.  *
  382.  *    This procedure is called back by the Pdev module whenever
  383.  *    a client tries to issue an ioctl on the pseudo-device associated
  384.  *    with a terminal.
  385.  *
  386.  * Results:
  387.  *    None.
  388.  *
  389.  * Side effects:
  390.  *    None.
  391.  *
  392.  *----------------------------------------------------------------------
  393.  */
  394.  
  395.     /* ARGSUSED */
  396. static int
  397. PdevIoctl(streamPtr, ioctlPtr, selectBitsPtr, sigPtr)
  398.     Pdev_Stream *streamPtr;    /* Service stream the client specified in its
  399.                  * kernel call. */
  400.     Pdev_IOCParam *ioctlPtr;    /* I/O control parameters */
  401.     int *selectBitsPtr;        /* Store new select state of terminal here. */
  402.     Pdev_Signal *sigPtr;    /* Returned signal, if any */
  403. {
  404.     register PdevTerm *ptPtr = (PdevTerm *) streamPtr->clientData;
  405.     int result;
  406.  
  407.     result = Td_ControlCooked(ptPtr->term, ioctlPtr->command,
  408.         ioctlPtr->format,
  409.         ioctlPtr->inBufSize, ioctlPtr->inBuffer,
  410.         &ioctlPtr->outBufSize, ioctlPtr->outBuffer,
  411.         &sigPtr->signal, &ptPtr->selectState);
  412.     *selectBitsPtr = ptPtr->selectState;
  413.     return result;
  414. }
  415.  
  416. /*
  417.  *----------------------------------------------------------------------
  418.  *
  419.  * CookedProc --
  420.  *
  421.  *    This procedure is called back by the Td module to inform
  422.  *    us of various things happening on the cooked side of the
  423.  *    terminal.
  424.  *
  425.  * Results:
  426.  *    The return value is the number of bytes of output data
  427.  *    stored at outBuffer (always 0 right now).
  428.  *
  429.  * Side effects:
  430.  *    Depends on the command;  read the code for details.
  431.  *
  432.  *----------------------------------------------------------------------
  433.  */
  434.  
  435.     /* ARGSUSED */
  436. static int
  437. CookedProc(ptPtr, command, inSize, inBuffer, outSize, outBuffer)
  438.     register PdevTerm *ptPtr;    /* Information about the pseudo-device
  439.                  * for the terminal. */
  440.     int command;        /* Identifies control operation being
  441.                  * invoked, e.g. TD_COOKED_SIGNAL. */
  442.     int inSize;            /* Number of bytes of input data available
  443.                  * to us. */
  444.     char *inBuffer;        /* Pointer to input data. */
  445.     int outSize;        /* Maximum number of bytes of output data
  446.                  * we can return to caller. */
  447.     char *outBuffer;        /* Area in which to store output data for
  448.                  * caller. */
  449. {
  450.     int result = 0;
  451.  
  452.     switch (command) {
  453.     case TD_COOKED_SIGNAL:
  454.         (void) Pdev_EnumStreams(ptPtr->pdev, SendSignal,
  455.             (ClientData) inBuffer);
  456.         break;
  457.     case TD_COOKED_READS_OK:
  458.         if (!(ptPtr->selectState & FS_READABLE)) {
  459.         ptPtr->selectState |= FS_READABLE;
  460.         (void) Pdev_EnumStreams(ptPtr->pdev, ChangeReady,
  461.             (ClientData) ptPtr->selectState);
  462.         }
  463.         break;
  464.     case TD_COOKED_WRITES_OK:
  465.         if (!(ptPtr->selectState & FS_WRITABLE)) {
  466.         ptPtr->selectState |= FS_WRITABLE;
  467.         (void) Pdev_EnumStreams(ptPtr->pdev, ChangeReady,
  468.             (ClientData) ptPtr->selectState);
  469.         }
  470.         break;
  471.     }
  472.     return result;
  473. }
  474.  
  475. /*
  476.  *----------------------------------------------------------------------
  477.  *
  478.  * ChangeReady --
  479.  *
  480.  *    This procedure is called back by Pdev_EnumStreams in order
  481.  *    to reset the readiness of all the streams associated with
  482.  *    a terminal.
  483.  *
  484.  * Results:
  485.  *    Always returns 0.
  486.  *
  487.  * Side effects:
  488.  *    The stream's select state is updated to match.
  489.  *
  490.  *----------------------------------------------------------------------
  491.  */
  492.  
  493. static int
  494. ChangeReady(streamPtr, selectState)
  495.     Pdev_Stream *streamPtr;        /* Information about the particular
  496.                      * stream. */
  497.     int selectState;            /* New select state for stream. */
  498. {
  499.     ReturnStatus status;
  500.  
  501.     status = Fs_IOControl(streamPtr->streamID, IOC_PDEV_READY,
  502.         sizeof(int), (Address) &selectState, 0, (Address) 0);
  503.     if (status != SUCCESS) {
  504.     panic("ChangeReady couldn't reset select state for pdev: %s",
  505.         Stat_GetMsg(status));
  506.     }
  507.     return 0;
  508. }
  509.  
  510. /*
  511.  *----------------------------------------------------------------------
  512.  *
  513.  * SendSignal --
  514.  *
  515.  *    This procedure is called back by Pdev_EnumStreams in order
  516.  *    to send a signal to the controlling process for a terminal.
  517.  *
  518.  * Results:
  519.  *    Always returns 1 to abort the enumeration after 1 stream
  520.  *    has been processed (there's no need to generate the signal
  521.  *    more than once).
  522.  *
  523.  * Side effects:
  524.  *    A signal is sent to the pseudo-device's controlling process (group).
  525.  *
  526.  *----------------------------------------------------------------------
  527.  */
  528.  
  529. static int
  530. SendSignal(streamPtr, sigInfoPtr)
  531.     Pdev_Stream *streamPtr;        /* Information about the particular
  532.                      * stream. */
  533.     Td_Signal *sigInfoPtr;        /* Information about signal to send. */
  534. {
  535.     ReturnStatus status;
  536.     Pdev_Signal sigInfo;
  537.  
  538.     status = Compat_UnixSignalToSprite(sigInfoPtr->sigNum, &sigInfo.signal);
  539.     if (status != SUCCESS) {
  540.     panic("SendSignal couldn't translate signal %d", sigInfoPtr->sigNum);
  541.     }
  542.     sigInfo.code = 0;
  543.  
  544.     /*
  545.      * Ignore errors in sending the signal:  they could happen because
  546.      * the user set a non-existent process group.
  547.      */
  548.  
  549.     (void) Fs_IOControl(streamPtr->streamID, IOC_PDEV_SIGNAL_OWNER,
  550.         sizeof(sigInfo), (Address) &sigInfo, 0, (Address) 0);
  551.     return 1;
  552. }
  553. @
  554.  
  555.  
  556. 1.7
  557. log
  558. @Bogus extra parameter was causing selectBits to get garbaged in
  559. kernel and making txinfo hang, among other things.
  560. @
  561. text
  562. @d18 1
  563. a18 1
  564. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyPdev.c,v 1.6 89/06/15 15:09:37 ouster Exp $ SPRITE (Berkeley)";
  565. d350 1
  566. @
  567.  
  568.  
  569. 1.6
  570. log
  571. @Lint.
  572. @
  573. text
  574. @d18 1
  575. a18 1
  576. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyPdev.c,v 1.5 89/06/03 16:47:26 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  577. d312 1
  578. a312 1
  579.     Pdev_EnumStreams(ptPtr->pdev, ChangeReady, &sigPtr->signal,
  580. @
  581.  
  582.  
  583. 1.5
  584. log
  585. @Several changes:  TD_HANGUP is now TD_GOT_CARRIER and TD_LOST_CARRIER,
  586. added TD_RAW_BAUD_RATE callback, changed TD_COOKED_SIGNAL to provide
  587. both signal number and controlling process group.
  588. @
  589. text
  590. @d18 1
  591. a18 1
  592. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyPdev.c,v 1.4 89/06/02 13:38:39 brent Exp Locker: ouster $ SPRITE (Berkeley)";
  593. d265 1
  594. a265 1
  595.     int result, sigNum;
  596. d347 1
  597. a347 1
  598.     int result, sigNum;
  599. @
  600.  
  601.  
  602. 1.4
  603. log
  604. @Updated to new pseudo-device interface with signals
  605. @
  606. text
  607. @d18 1
  608. a18 1
  609. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyPdev.c,v 1.3 89/04/20 10:24:21 ouster Exp Locker: brent $ SPRITE (Berkeley)";
  610. d396 1
  611. a396 1
  612.             (ClientData) *((int *) inBuffer));
  613. d471 1
  614. a471 1
  615. SendSignal(streamPtr, signal)
  616. d474 1
  617. a474 1
  618.     int signal;                /* Signal to send. */
  619. d479 1
  620. a479 1
  621.     status = Compat_UnixSignalToSprite(signal, &sigInfo.signal);
  622. d481 1
  623. a481 1
  624.     panic("SendSignal couldn't translate signal %d", signal);
  625. @
  626.  
  627.  
  628. 1.3
  629. log
  630. @Removed log code:  no longer needed.
  631. @
  632. text
  633. @d18 1
  634. a18 1
  635. static char rcsid[] = "$Header: /a/newcmds/tty/RCS/ttyPdev.c,v 1.4 89/03/23 15:26:08 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  636. d256 1
  637. a256 2
  638. PdevRead(streamPtr, offset, procID, familyID, numBytesPtr, bufferPtr,
  639.     freeItPtr, selectBitsPtr)
  640. d259 2
  641. a260 8
  642.     int offset;            /* Position within file;  ignored. */
  643.     int procID;            /* Name of reading process. */
  644.     int familyID;        /* Process group to which procID belongs. */
  645.     int *numBytesPtr;        /* Points to number of bytes wanted;
  646.                  * overwritten with number of bytes actually
  647.                  * supplied. */
  648.     char **bufferPtr;        /* Pointer to pointer to buffer in which to
  649.                  * store data. */
  650. d263 1
  651. d268 3
  652. a270 5
  653.     result = Td_GetCooked(ptPtr->term, procID, familyID, numBytesPtr,
  654.         *bufferPtr, &sigNum, &ptPtr->selectState);
  655.     if (sigNum != 0) {
  656.     (void) kill(procID, sigNum);
  657.     }
  658. d295 1
  659. a295 2
  660. PdevWrite(streamPtr, async, offset, procID, familyID, numBytesPtr,
  661.     buffer, selectBitsPtr)
  662. d300 2
  663. a301 8
  664.     int offset;            /* Not used. */
  665.     int procID;            /* Not used. */
  666.     int familyID;        /* Not used. */
  667.     int *numBytesPtr;        /* Points to number of bytes the client wants
  668.                  * to write; overwritten with number of
  669.                  * bytes actually accepted. */
  670.     char *buffer;        /* Pointer to buffer containing data to be
  671.                  * be written. */
  672. d303 1
  673. d306 1
  674. a306 1
  675.     int oldBits, result, sigNum;
  676. d309 2
  677. a310 5
  678.     result = Td_PutCooked(ptPtr->term, numBytesPtr, buffer, &sigNum,
  679.         &ptPtr->selectState);
  680.     if (sigNum != 0) {
  681.     (void) kill(procID, sigNum);
  682.     }
  683. d312 1
  684. a312 1
  685.     Pdev_EnumStreams(ptPtr->pdev, ChangeReady, &sigNum,
  686. d339 1
  687. a339 2
  688. PdevIoctl(streamPtr, command, procID, familyID, byteOrder, inSize, inBuffer,
  689.     outSizePtr, outBuffer, selectBitsPtr)
  690. d342 1
  691. a342 14
  692.     int command;        /* Ioctl command (e.g. IOC_TTY_SETP). */
  693.     int procID;            /* Not used. */
  694.     int familyID;        /* Not used. */
  695.     int byteOrder;        /* Identifies data format of host on which
  696.                  * the client is running. */
  697.     int inSize;            /* Number of bytes of data in inBuffer. */
  698.     char *inBuffer;        /* Pointer to buffer containing input data
  699.                  * for ioctl. */
  700.     int *outSizePtr;        /* Pointer to maximum number of bytes of
  701.                  * output data wanted by client.  Gets
  702.                  * overwritten with the amount supplied. */
  703.     char *outBuffer;        /* Pointer to buffer in which to store
  704.                  * output data.  Guaranteed to have at
  705.                  * least *outSizePtr bytes of space. */
  706. d344 1
  707. d349 4
  708. a352 5
  709.     result = Td_ControlCooked(ptPtr->term, command, inSize, inBuffer,
  710.         outSizePtr, outBuffer, &sigNum, &ptPtr->selectState);
  711.     if (sigNum != 0) {
  712.     (void) kill(procID, sigNum);
  713.     }
  714. @
  715.  
  716.  
  717. 1.2
  718. log
  719. @Slight improvement to tracing code.
  720. @
  721. text
  722. @a48 30
  723.  * Temporary log to track down rlogin lock-up problem:
  724.  */
  725.  
  726. typedef struct {
  727.     int operation;            /* See #defines below. */
  728.     int selectState;
  729.     int otherData;
  730. } LogEntry;
  731.  
  732. #define BEFORE_OPEN    1
  733. #define AFTER_OPEN    2
  734. #define BEFORE_READ    3
  735. #define AFTER_READ    4
  736. #define BEFORE_WRITE    5
  737. #define AFTER_WRITE    6
  738. #define BEFORE_IOCTL    7
  739. #define AFTER_IOCTL    8
  740. #define READS_OK    9
  741. #define WRITES_OK    10
  742.  
  743. static LogEntry log[256];
  744. static int logCurrent;
  745.  
  746. #define LOG(op, state, other)            \
  747.     log[logCurrent].operation = (op);        \
  748.     log[logCurrent].selectState = (state);    \
  749.     log[logCurrent].otherData = (other);    \
  750.     logCurrent = (logCurrent+1) & 0xff;
  751.  
  752. /*
  753. a198 1
  754.     LOG(BEFORE_OPEN, ptPtr->selectState, 0);
  755. a199 1
  756.     LOG(AFTER_OPEN, ptPtr->selectState, result);
  757. a273 1
  758.     LOG(BEFORE_READ, ptPtr->selectState, *numBytesPtr);
  759. a275 1
  760.     LOG(AFTER_READ, ptPtr->selectState, result);
  761. a322 1
  762.     LOG(BEFORE_WRITE, ptPtr->selectState, *numBytesPtr);
  763. a324 1
  764.     LOG(AFTER_WRITE, ptPtr->selectState, result);
  765. a378 1
  766.     LOG(BEFORE_IOCTL, ptPtr->selectState, command);
  767. a380 1
  768.     LOG(AFTER_IOCTL, ptPtr->selectState, result);
  769. a429 1
  770.         LOG(READS_OK, ptPtr->selectState, 0);
  771. a436 1
  772.         LOG(WRITES_OK, ptPtr->selectState, 0);
  773. @
  774.  
  775.  
  776. 1.1
  777. log
  778. @Initial revision
  779. @
  780. text
  781. @d468 1
  782. a472 1
  783.         LOG(READS_OK, ptPtr->selectState, 0);
  784. d476 1
  785. a480 1
  786.         LOG(WRITES_OK, ptPtr->selectState, 0);
  787. @
  788.